package com.frame.work.frame.deal.gateway;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.frame.work.common.base.core.CoreServer;
import com.frame.work.common.util.FrameMaker;
import com.frame.work.common.util.Time;
import com.frame.work.entity.TblDevice;
import com.frame.work.entity.TblDeviceActions;
import com.frame.work.mapper.TblDeviceMapper;
import com.frame.work.mqtt.Topic;
import com.frame.work.mqtt.data.handle.MqttDataHandle;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Component;

import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 设备入网或者离网配置
 *
 * @author wjming
 */
@Component
@Slf4j(topic = "配置信息")
public class Device60FrameDeal {
    @Autowired
    private MqttDataHandle mqttDataHandle;

    @Autowired
    private StringRedisTemplate redisTemplate;

    @Autowired
    private TblDeviceMapper deviceMapper;

    @Autowired
    private CoreServer coreServer;
    @Autowired
    private RabbitTemplate rabbitTemplate;

    @Value("${topic.rabbit.generalQueueProcessing}")
    private String generalQueueProcessing;

    public void frameDeal(String gatewayMac, String data, Object channel) {
        try {
            // 子命令标识
            String childCmd = StringUtils.substring(data, 22, 24);
            // 节点状态（02表示入网成功 03表示离网成功）
            String nodeState = StringUtils.substring(data, 24, 26);
            // 节点MAC
            String deviceMac = StringUtils.substring(data, 26, 42);
            if (childCmd.equals("03")) {
                //入网成功
                if (nodeState.equals("02")) {
                    Map<String, Object> retMsg = new HashMap<>();
                    retMsg.put("returnTime", Time.NowTimeToSecond());
                    retMsg.put("gateway_mac", gatewayMac);
                    retMsg.put("device_mac", deviceMac);
                    retMsg.put("message", "设备入网成功");
                    mqttDataHandle.mqttPush(gatewayMac + "_60", JSONObject.toJSONString(retMsg));
                    coreServer.writeDataToGateWay(FrameMaker.getWriteGatewayReadDevice1007Frame(gatewayMac, deviceMac), channel);
                }
                //离网成功
                else if (nodeState.equals("03")) {
                    Map<String, Object> retMsg = new HashMap<>();
                    retMsg.put("returnTime", Time.NowTimeToSecond());
                    retMsg.put("gateway_mac", gatewayMac);
                    retMsg.put("device_mac", deviceMac);
                    retMsg.put("lwbz", 1);
                    retMsg.put("message", "设备离网成功");
                    //修改zigbee设备中的设备信息
                    TblDevice tblDevice = TblDevice.builder().lwbz("1").switchTime(LocalDateTime.now()).build();
                    int update = deviceMapper.update(tblDevice, Wrappers.<TblDevice>lambdaQuery().eq(TblDevice::getZigbeeMac, deviceMac));
                    if (update < 1) {
                        System.out.println("离网信息修改失败,或设备不存在");
                    }
                    mqttDataHandle.mqttPush(gatewayMac, JSONObject.toJSONString(retMsg));
                }
            }
        } catch (Exception e) {
            System.out.println("入网或离网异常:" + e.getMessage());
        }

    }

    /**
     * @param gatewayMac
     * @param data
     */
    public void frame0000Deal(String gatewayMac, String data) {
        String deviceMac = StringUtils.substring(data, 2, 18);
        String version = StringUtils.substring(data, data.length() - 8);
        Map<String, Object> retMeg = new HashMap<>();
        retMeg.put("returnTime", Time.NowTimeToSecond());
        retMeg.put("gatewayMac", gatewayMac);
        retMeg.put("deviceMac", deviceMac);
        retMeg.put("actions", new HashMap<String, Object>().put("version", version));
        //修改数据库离线标识
        TblDevice tblDevice = TblDevice.builder().lwbz("0").switchTime(LocalDateTime.now()).build();
        int update = deviceMapper.update(tblDevice, Wrappers.<TblDevice>lambdaQuery().eq(TblDevice::getZigbeeMac, deviceMac));
        if (update < 1) {
            System.out.println("离线重连失败");
        }
        mqttDataHandle.offlineReconnection(gatewayMac, JSONObject.toJSONString(retMeg));
    }

    public void frame02setDeal(String gatewayMac, String data) {
        String deviceMac = StringUtils.substring(data, 2, 18);
        String odIndex = StringUtils.substring(data, 18, 22);
        String Subindex = StringUtils.substring(data, 22, 24);
        String reply = StringUtils.substring(data, 24, 26);
        //继电器配置回应信息
        if ("15".equals(Subindex)) {
            log.info("[frameDeal] -> [gatewayMac:{},data{}]", gatewayMac, data);
            String redisValue = redisTemplate.opsForValue().get("zyzn_relayControl_gatewayMac_" + gatewayMac);
            JSONObject jsonObject = new JSONObject();
            jsonObject = (JSONObject) JSONObject.parse(redisValue);
            if (!StringUtils.isEmpty(redisValue)) {
                //00代表配置成功
                if ("00".equals(reply)) {
                    String state = "SUCCESS";
                    Map<String, Object> modifyMessage = new HashMap<>();
                    modifyMessage.put("dealType", "setRelayMode");
                    modifyMessage.put("id", jsonObject.get("id"));
                    modifyMessage.put("controlType", jsonObject.get("controlType"));
                    rabbitTemplate.convertAndSend(generalQueueProcessing, modifyMessage);
                }

                Map<String, Object> returnMessage = new HashMap<>();
                returnMessage.put("gatewayMac", gatewayMac);
                returnMessage.put("zigbeeMac", jsonObject.get("deviceMac"));
                returnMessage.put("odIndex", jsonObject.get("odIndex"));
                returnMessage.put("productType", jsonObject.get("productType"));
                returnMessage.put("controlType", jsonObject.get("controlType"));
                returnMessage.put("deviceType", jsonObject.get("deviceType"));
                returnMessage.put("type", "relay");
                returnMessage.put("state", reply);
                mqttDataHandle.basePush(Topic.device.topics + gatewayMac + Topic.relay, JSONObject.toJSONString(returnMessage));
                Boolean delete = redisTemplate.delete("zyzn_relayControl_gatewayMac_" + gatewayMac);
                if (delete) {
                    System.out.println("redis删除成功");
                }
                return;
            }
        }

        System.out.println("回复状态" + reply);
        System.out.println("网关mac" + gatewayMac);
        System.out.println("数据帧" + data);

        String od_index = "0FAA";
        String device_type = "02";
        //强电控制盒
        String product_type_02 = "02";
        //弱电控制盒
        String product_type_03 = "03";
        //查询信息
        QueryWrapper<TblDevice> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("zigbee_mac", deviceMac);
        queryWrapper.eq("od_index", od_index);
        queryWrapper.eq("device_type", device_type);
        queryWrapper.eq("product_type", product_type_02).or().eq("product_type", product_type_03);

        List<TblDeviceActions> deviceActions = deviceMapper.selectByZigbeeMac(deviceMac, od_index, device_type, product_type_02, product_type_03);
        if (CollectionUtils.isEmpty(deviceActions)) {
            Map<String, Object> returnMessage = new HashMap<>();
            returnMessage.put("gatewayMac", gatewayMac);
            returnMessage.put("deviceMac", deviceMac);
            returnMessage.put("odIndex", odIndex);
            returnMessage.put("deviceType", "");
            returnMessage.put("productType", "");
            returnMessage.put("actions", new HashMap<>());
            mqttDataHandle.basePush(gatewayMac, JSONObject.toJSONString(returnMessage));
            return;
        }
        if (deviceActions.size() > 0) {
            deviceActions.stream().forEach(devAction -> {
                if (devAction.getActionsKey().equals("motorTimeParameter")) {
                    String actionsValue = devAction.getActionsValue();
                    Map<String, Object> returnMessage = new HashMap<>(6);
                    returnMessage.put("gatewayMac", gatewayMac);
                    returnMessage.put("deviceMac", deviceMac);
                    returnMessage.put("odIndex", odIndex);
                    returnMessage.put("deviceType", "");
                    returnMessage.put("productType", "");
                    returnMessage.put("actions", new HashMap<>(1).put("motorTimeParameter", actionsValue));
                    mqttDataHandle.basePush(gatewayMac, JSONObject.toJSONString(returnMessage));
                }
            });
        }

        //修改入网标识
        int update = deviceMapper.update(TblDevice.builder().lwbz("0").build(), Wrappers.<TblDevice>lambdaQuery()
                .eq(TblDevice::getZigbeeMac, deviceMac));
        if (update < 1) {
            System.out.println("修改失败: " + deviceMac);
        }

    }

    public void frame1007Deal(String gatewayMac, String data) {
        String cardState = null;
        String deviceMac = StringUtils.substring(data, 2, 18);
        String od = StringUtils.substring(data, 26, 30);
        String odIndex = StringUtils.substring(od, 2, 4) + StringUtils.substring(od, 0, 2);
        String deviceType = StringUtils.substring(data, 30, 32);
        String productType = StringUtils.substring(data, 32, 34);
        String spreadingType = StringUtils.substring(data, 34, 36);
        Map<String, Object> returnMessage = new HashMap<>(6);
        Map<String, Object> action = new HashMap<>(2);
        returnMessage.put("gatewayMac", gatewayMac);
        returnMessage.put("deviceMac", deviceMac);
        returnMessage.put("odIndex", odIndex);
        returnMessage.put("deviceType", deviceType);
        returnMessage.put("productType", productType);
        returnMessage.put("spreadingType", spreadingType);

        if ("0FAA".equals(odIndex) && "81".equals(deviceType) && "06".equals(productType)) {
            String laterTime = StringUtils.substring(data, data.length() - 10, data.length() - 8);

            List<TblDeviceActions> deviceActions = deviceMapper.selectActionByDeviceMessage(deviceMac, odIndex, deviceType, productType);
            if (CollectionUtils.isNotEmpty(deviceActions)) {
                for (TblDeviceActions deviceAction : deviceActions) {
                    if ("cardState".equals(deviceAction.getActionsKey())) {
                        cardState = deviceAction.getActionsValue();
                    }
                }
                action.put("laterTime", Integer.parseInt(laterTime, 16)+"");
                action.put("cardState", cardState);
                returnMessage.put("actions", action);
                mqttDataHandle.mqttPushModifyAction(gatewayMac + '_' + deviceMac + "_param", JSONObject.toJSONString(returnMessage));
            }
        } else if ("0FAA".equals(odIndex) && "8A".equalsIgnoreCase(deviceType) && "0A".equalsIgnoreCase(productType)) {
            String switchCount = StringUtils.substring(data, 42, 44);
            String sceneCount = StringUtils.substring(data, 44, 46);
            action.put("switchCount", switchCount);
            action.put("sceneCount", sceneCount);
            returnMessage.put("actions", action);
            mqttDataHandle.mqttPush(gatewayMac + '_' + deviceMac + "_param", JSONObject.toJSONString(returnMessage));
        } else {
            returnMessage.put("actions", new HashMap<>(0));
            mqttDataHandle.mqttPush(gatewayMac + '_' + deviceMac + "_param", JSONObject.toJSONString(returnMessage));
        }
        TblDevice tblDevice = new TblDevice();
        tblDevice.setLwbz("0");
        try {
            int update = deviceMapper.update(tblDevice, Wrappers.<TblDevice>lambdaQuery().eq(TblDevice::getZigbeeMac, deviceMac));
            if (update < 1) {
                System.out.println("设备信息修改失败 = " + deviceMac);
            }
        } catch (Exception e) {
            System.out.println("设备信息修改失败 = " + e.getMessage());
        }


    }
}
